/* ----------------------------- Noble Steed Engine----------------------------*
Authors : Daniel Randle, Alex Bourne
Date Created : Mar 19 2013

File:
	nsobjectreferenceset.h

Description:
	This file contains the NSObjectReferenceSet class which is the base container for all the object
	references in the game
*---------------------------------------------------------------------------*/

#ifndef NSOBJECTREFERENCESET_H
#define NSOBJECTREFERENCESET_H

/* ---------------------------------Class NSObjectReferenceSet-----------------------------*

Description:
	NSObjectReferenceSet will provide all the needed functions to update all of the references in the game

*-------------------------------------------------------------------------------*/

// includes
#include <nsmath3d.h>
#include <vector>
#include <map>
#include <Windows.h>

class NSMapArea;
class NSObject;
class NSObjectReference;
class NSObjectSet;

class NSObjectReferenceSet
{
public:
	typedef std::map<NSObject*,std::vector<NSObjectReference*>>::iterator Iterator;
	typedef std::vector<NSObjectReference*>::iterator RefIterator;

	NSObjectReferenceSet(NSMapArea * mapArea);
	~NSObjectReferenceSet();

	void addReference(NSObjectReference  * toAdd);
	void addReference( NSObject * objPtr,const NSVec3Df & pos = NSVec3Df(),const NSVec3Df & orient = NSVec3Df(),const NSVec3Df & _scale = NSVec3Df(1.0f,1.0f,1.0f) );

	void clear();
	bool contains(NSObject * object);

	unsigned int getObjectCount();
	NSObjectReference* getReference(unsigned int referenceID, NSObject * baseObj);
	unsigned int getReferenceCount(NSObject * baseObj);
	unsigned int getTotalReferenceCount();

	bool removeAllReferencesOf(NSObject * base);
	bool removeReference(unsigned int referenceID, NSObject * baseObj);
	bool removeReference(NSObjectReference* reference);

	void setRefsProjMat(const NSMatrix4Df & projMat);
	void DoThread(std::vector<NSObjectReference*>* list, int si, int size);

	void update(NSObject * base);  // Update all references that are references of this object
	void updateAll();

	Iterator begin();
	Iterator end();
	RefIterator refBegin(NSObject * baseObj);
	RefIterator refEnd(NSObject * baseObj);

	static DWORD WINAPI MyThreadFunction( LPVOID lpParam );
private:
	struct Param
	{
		std::vector<NSObjectReference*>* list;
		int startIndex;
		int size;
		NSObjectReferenceSet* th;
	};
	
	NSMapArea * mapArea;
	std::map<NSObject*,std::vector<NSObjectReference*>> references;
	std::vector<NSObjectReference*> empty; // this is in case refBegin is
	// given an object that is not in the reference set
};


#endif